#!/usr/bin/env python
# encoding: utf-8
'''
Adb.PowerMonitor -- Power monitor

Adb.PowerMonitor is a mudule monitoring the devices power on/off state

It defines classes_and_methods

@author:     Anson Chan

@copyright:  2016 Xerland Co. Ltd. All rights reserved.

@contact:    anson_chan@xerland.com
@deffield    updated: Updated
'''
from datetime import datetime
from Adb.RsHelper import RsHelper
from Utils.Singleton import Singleton
from Utils.SysConstants import *
from Adb.MachModel import MachModel
import pythoncom
from Adb.RtdMonitor import RtdMonitor
from Utils.TimeStamp import strDateDelta
from copy import copy, deepcopy
import time

class PowerMonitor(RsHelper, Singleton):
    '''
    classdocs
    '''


    def __init__(self):
        '''
        Constructor
        '''
        self.machPowerRsHelper=RsHelper("MachPower")
        self.mMonitorMachList = self.getMachSet()
        self.mMachPowerStateList = self.getMachPowerState()
        self.mPowerStateLostTimeout = int(SERVERAPI_CONFIGSERVICE.getValue("tp_powerstate_lost_timeout"))
        
        
#    def getUpdate(self):
#        machPowerUpdateList = self.machPowerRsHelper.selectUpdate( "PowerOnTime")
        
        
    def getMachSet(self):
        monitorMachList = []
        machSet = SERVERAPI_CONFIGSERVICE.getValue("mach_set")
        machSet = eval(machSet)
        for machId in xrange(1,TPLUS_MAX_MACH_NUM+1):
            if machSet&0x01:
#                monitorMachIdList.append(machId)
                machRsHelper = RsHelper(ADB_MACH_CONF_RS_NAME)
                machRs=machRsHelper.selectColsWhere(["MachName"], "MachID=%d"%(machId))
                if  not machRs.EOF:
                    mach = MachModel(machId, machRs.Fields.Item(0).Value)
                    monitorMachList.append(mach)
                machRsHelper.close()
            machSet >>= 1
        return monitorMachList
    
    def getMachPowerState(self, machModel=None):
#        machPowerStateDict = {}
        machPowerStateList = self.getMachPowerStateRaw(machModel)
        if machModel == None: # regular update,
            machPowerStateList = self.reviseLostPowerStateList(machPowerStateList)
            print "list before trim:",printList(machPowerStateList)
            machPowerStateList = self.trimUnchangedPowerStateList(machPowerStateList)
            print "list after trim:",printList(machPowerStateList)
        elif machModel == []:
            machPowerStateList = self.reviseLostPowerStateList(machPowerStateList)
        self.updatePowerStateCache(machPowerStateList)
        return machPowerStateList
                
    def getMachPowerStateRaw(self, machModel=None):
        machPowerStateRawList = []
        if machModel:
            machPowerStateList = [machModel]
        else:
            machPowerStateList = deepcopy(self.mMonitorMachList)
        for mach in machPowerStateList:
            
            machPowerRsHelper = RsHelper(ADB_MACH_POWER_RS_NAME)
            machPowerRs=machPowerRsHelper.selectColsWhere(["RecordID","PowerOffTime", "PowerOnTime"], "MachID=%d"%(mach.getMachId()))
            if not machPowerRs.EOF:
                machPowerRs.MoveLast()
#                rId = machPowerRs.Fields.Item("RecordID").Value
                powerOnTimeRs = str(machPowerRs.Fields.Item("PowerOnTime").Value)
                powerOffTimeRs = str(machPowerRs.Fields.Item("PowerOffTime").Value)

                mach.setPowerOnTime(powerOnTimeRs)
                mach.setPowerOffTime(powerOffTimeRs)
                
                machPowerStateRawList.append(mach)
            machPowerRsHelper.close()
            
        return machPowerStateRawList
    
    def trimUnchangedPowerStateList(self, powerStateList):
        changedList = []
        for powerState in powerStateList:
            for powerStateCache in self.mMonitorMachList:
                if powerState.getMachId() == powerStateCache.getMachId():
                    print "poweroff:",powerState.getPowerOffTime()," vs ",powerStateCache.getPowerOffTime()
                    print "poweron:",powerState.getPowerOnTime()," vs ",powerStateCache.getPowerOnTime()
                    if powerState.getPowerOffTime() != powerStateCache.getPowerOffTime()\
                    or powerState.getPowerOnTime() != powerStateCache.getPowerOnTime():
                        changedList.append(powerState)
        return changedList
                
    def reviseLostPowerStateList(self, powerStateList):
        for powerState in powerStateList:
            if powerState.getPowerState() == TPLUS_MACH_POWER_STATE_ON:
                recentSaveTime = RtdMonitor.getRecentSaveTimeById(powerState.getMachId())
                print "recentSaveTime is",recentSaveTime
                if recentSaveTime and strDateDelta(getNowDate(), recentSaveTime).seconds > self.mPowerStateLostTimeout \
                or not recentSaveTime:
                    powerState.setPowerOffTime(TPLUS_ABNORMAL_DATETIME)
                print 'powerState poweroff time is', powerState.getPowerOffTime()
        return powerStateList
    
    def updatePowerStateCache(self, powerStateList):
        for powerState in powerStateList:
            for powerStateCache in self.mMonitorMachList:
                if powerState.getMachId() == powerStateCache.getMachId():
                    powerStateCache.setPowerOffTime(powerState.getPowerOffTime())
                    powerStateCache.setPowerOnTime(powerState.getPowerOnTime())
                    
def printList(stateList):
    for state in stateList:
        print state.getMachId(),state.getMachName(),state.getPowerOffTime(), state.getPowerOnTime()
                    
if __name__ == "__main__":
    powerMonitor = PowerMonitor()
    for powerstate in powerMonitor.getMachPowerState(MachModel(2,"")):
        print powerstate.getMachName(), powerstate.getPowerOffTime(), powerstate.getPowerOnTime()
    print '.'*100
    time.sleep(120)
    for powerstate in powerMonitor.getMachPowerState():
        print powerstate.getMachName(), powerstate.getPowerOffTime(), powerstate.getPowerOnTime()    
        
        
        
            
                                    
                
                
            
        
    
        